#!/usr/bin/env python
#coding=utf-8
from config import FILEPATH_R,FILEPATH_N,BITFILE_PATH, \
    FLOAT_THRESHOLD,FLOATCOST,TOP_ATTR,DISCRET_INDEX_FILE,LAST_INDEX

#切分数据
#读源数据
def ReadDataSource(filepath):
    file = open(filepath,"r")
    lines = file.readlines()
    dataSource = []
    #读第一行,获取列数
    lines[0] = lines[0].rstrip()#除去最后一个回车符
    arrColumn = lines[0].split(',')
    #将所有数据读入list
    for i in range(len(arrColumn)):
        dataSource.append([])#插入一列 
               
    #读取每行
    for i in range(1,len(lines)):
        lines[i] = lines[i].rstrip()
        arr = lines[i].split(',')
        for j in range(len(arrColumn)):
            dataSource[j].append(arr[j])
        #print i
    return dataSource

#读索引数据
def GetSourceIndex(filepath):
    file = open (filepath,"r")
    lines = file.readlines()#读进了一个列表
    #print lines
    data = ""
    numIndexArray = []
    for i in range(len(lines)):
        lines[i] = lines[i].strip()
        arr = lines[i].split(' ')
        #fieldName,fieldType = arr[0],arr[-1]
        #numIndexArray.append((i,fieldName,fieldType,i))
        numIndexArray.append([])
        for j in range(len(arr)):
            numIndexArray[i].append(arr[j])
    file.close()
    #print numIndexArray
    return numIndexArray


def GetClass(Dr,Dn):
    RowClass = []
    #给每一个属性列加入一个列表
    #统计每列中每个属性的数量
    for i in range(len(Dr)-2):#对于每一列
        RowClass.append([])#格式 0(属性) 1(Dr中出现次数) 2(Dn中出现次数) 3(此属性总收益)
        for ir in range(len(Dr[i])):#对于每一行
            if (Dr[i][ir]).strip() != '':
                intTemp = -1
                for j in range(len(RowClass[i])):
                    if Dr[i][ir] == RowClass[i][j][0]:
                        intTemp = j
                        break
                if intTemp == -1:
                    fk = float(Dr[len(Dr)-1][ir])
                    # 实际处理过程中，没有出现一个属性出现多个属性值的情况
                    RowClass[i].append([Dr[i][ir],1,0,fk,i])#加入新元组
                else:
                    RowClass[i][intTemp][1] += 1
                    RowClass[i][intTemp][3] += float(Dr[len(Dr)-1][ir])
    #统计Dn中RowClass数目
    for i in range(len(RowClass)):
        for j in range(len(RowClass[i])):
            for k in range(len(Dn[i])):
                if Dn[i][k] == RowClass[i][j][0]:
                    RowClass[i][j][2] += 1
    '''for i in range(len(RowClass)):
        if len(RowClass[i]) > 200:
            print i'''
    #print RowClass[0]
    print "GetClass finished!"
    return RowClass

def BitTransform(RowClass,floatThrehold,floatCost):
    la = []
    Rowleft = []
    #存放价值最高的TOP_ATTR个属性
    top_ivs = []#从大到小排,#排序插入其中,插入[属性编号,属性值,属性收益]
    #存放找
    RowTop = []
    # print "RowClass:"+str(RowClass)
    for i in range(len(RowClass)):
        #la.append([])
        Rowleft.append([])#留下的属性值
        temp = 0
        # 对每一个属性的多个属性值进行统计
        for j in range(len(RowClass[i])):
            profit = float(RowClass[i][j][3])
            cost = float((RowClass[i][j][1]+RowClass[i][j][2])*float(floatCost))
            threhold = float(floatThrehold)
                        
            ##########################################
            #在此统计Top100属性值
            if len(top_ivs) == 0:
                top_ivs.insert(0,[i,RowClass[i][j][0],profit])
            elif len(top_ivs) < TOP_ATTR:
                #插入排序,插入属性编号,属性值,属性收益
                for kkk in range(len(top_ivs)):
                    if profit > top_ivs[kkk][2] and len(top_ivs) > 0:
                        top_ivs.insert(kkk,[i,RowClass[i][j][0],profit])
                        break
            else:
                # 当元素个数超过TOP_ATTR时，插入一个，删除
                for mmm in range(len(top_ivs)):
                    if profit > top_ivs[mmm][2]:
                        top_ivs.insert(mmm,[i,RowClass[i][j][0],profit])
                        del top_ivs[len(top_ivs)-1]
                        break                    
            ##########################
            
            if profit > (cost * threhold):
                # RowClass[i][j][1]:Dr中出现次数,RowClass[i][j][0]:属性值
                temp += RowClass[i][j][1]
                Rowleft[i].append(RowClass[i][j][0])
        la.append(temp)

    ################################################
    #在此统计选取的属性列,放入RowTop[]
    for iijj in range(len(top_ivs)):
        if len(RowTop) == 0:
            RowTop.append(top_ivs[iijj][0])
        else:
            intTempii = 0
            for iikk in range(len(RowTop)):
                # 该列已经放入
                if RowTop[iikk] == top_ivs[iijj][0]:
                    intTempii = 1
                    break
            if intTempii == 0:
                RowTop.append(top_ivs[iijj][0])
    #排序,对RowTop进行排序
    RowTop.sort()
    print 'Length of Data RowTop:'+str(len(RowTop))
    ################################################
    ###################建立新的索引文件
    #首先读取indexLast.txt,然后筛选出合格的属性区间,并建立新索引
    #新索引格式为
    #标号 列名 类型(Num) 分类数 Xmin Xmax ...
    #标号 列名 类型(Char) XChar
    
    #step1 关联indexLast.txt,获取最小,最大,分类数,然后关联Rowleft,提取要保留的属性区间
    Rowindex = GetSourceIndex(DISCRET_INDEX_FILE)
    RowRes = []
    
    for i in range(len(RowTop)):
        RowRes.append([RowTop[i]])
        #提取列名与类型
        RowRes[i].append(Rowindex[RowTop[i]-1][1])#添加列名
        RowRes[i].append(Rowindex[RowTop[i]-1][2])#添加类型
        if RowRes[i][2] == 'Num':
            #读Rowleft,再读
            RowRes[i].append(Rowindex[RowTop[i]-1][3])#添加分类数
            RowRes[i].append(Rowindex[RowTop[i]-1][4])#添加属性Min
            RowRes[i].append(Rowindex[RowTop[i]-1][5])#添加属性Max
            for j in range(len(Rowleft[RowTop[i]-1])):
                RowRes[i].append(Rowleft[RowTop[i]-1][j])#添加属性选择项
        else:
            for j in range(len(Rowleft[RowTop[i]-1])):
                RowRes[i].append(Rowleft[RowTop[i]-1][j])#添加属性选择项
    
    #for i in range(len(RowRes)):
        #print RowRes[i]
    #写索引文件
    fileindex = open(LAST_INDEX,"w")
    for i in range(len(RowRes)):
        for j in range(len(RowRes[i])-1):
            fileindex.write(str(RowRes[i][j]) + ' ')
        fileindex.write(str(RowRes[i][len(RowRes[i])-1]) + ' \n')
    print "write index file finish:"+LAST_INDEX
            
    
    ###################################
    
    ccc = 0
    bbb = 0
    for i in range(len(la)):
        if la[i] > 0:
            stri = str(i) + ' ' + str(la[i])
            #print stri
            ccc += 1
            bbb += la[i]
            #print la[i]
    #print ccc
    ddd = round( float(bbb)*100/(3270*466),2 )
    print "1所占比例为:"+str(ddd)+"%"
    
    return Rowleft

def WriteBit(Dr,Rowleft):
    BitDr = []
    Rowindex = GetSourceIndex(LAST_INDEX)
    #初始化
    for i in range(len(Rowindex)+2):
        BitDr.append([])
        for j in range(len(Dr[0])):
            BitDr[i].append('0')
    for i in range(len(Rowindex)):
        for j in range(len(Rowleft[int(Rowindex[i][0])-1])):
            for m in range(len(Dr[int(Rowindex[i][0])-1])):
                if Dr[int(Rowindex[i][0])-1][m] == Rowleft[int(Rowindex[i][0])-1][j]:
                    BitDr[i][m] = '1'
    for j in range(len(BitDr[0])):
        BitDr[len(BitDr)-2][j] = Dr[len(Dr)-2][j]
        BitDr[len(BitDr)-1][j] = Dr[len(Dr)-1][j]        
    #写结果文件
    file = open(BITFILE_PATH,"w")
    for i in range(len(BitDr)-1):
        file.write(str(i+1) + ',')
    file.write(str(len(BitDr)) + '\n')
        
    for i in range(len(BitDr[0])):
        for j in range(len(BitDr)-1):
            file.write(str(BitDr[j][i]) + ',')
        file.write(str(BitDr[len(BitDr)-1][i]) + '\n')
    print "write dataSource file finish:"+BITFILE_PATH
                
if __name__ == "__main__":
    filepath_r = FILEPATH_R #Response数据源
    filepath_n = FILEPATH_N #Non-response数据源
    floatThrehold = FLOAT_THRESHOLD #平均收益比
    floatCost = FLOATCOST #每封信成本
    Dr = ReadDataSource(filepath_r)
    Dn = ReadDataSource(filepath_n)
    RowClass = GetClass(Dr,Dn)
    Rowleft = BitTransform(RowClass,floatThrehold,floatCost)
    WriteBit(Dr,Rowleft)
    
